/*
 * User: gilad
 * Date: 15/05/2008 
 *
 * Copyright (2005) IDI. All rights reserved.
 * This software is a proprietary information of Israeli Direct Insurance.
 * Created by IntelliJ IDEA. 
 */
package com.idi.maven.plugins.servers;

import com.idi.maven.plugins.BareketBuildProperties;
import com.idi.maven.plugins.BuildPropertiesFactory;
import com.idi.maven.plugins.DeploymentHelper;
import com.idi.remote.assistant.RemoteAccessFacade;
import com.idi.remote.assistant.SshExecClient;
import org.apache.maven.plugin.MojoExecutionException;
import org.jfrog.jade.plugins.common.injectable.MvnInjectable;
import org.jfrog.jade.plugins.common.injectable.MvnInjectableSupport;

import java.io.IOException;
import static java.lang.String.format;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 *
 */
public class BareketServerImpl extends MvnInjectableSupport implements Server {

    private final String jndiServer;
    private final DeploymentHelper deploymentHelper;
    private final BareketBuildProperties serverProperties;
    private final RemoteAccessFacade remoteAccessFacade;

    public BareketServerImpl(String jndiServer) {
        this.jndiServer = jndiServer;
        serverProperties = BuildPropertiesFactory.createBuildPropertiesForWebServer(jndiServer);
        deploymentHelper = new DeploymentHelper(serverProperties, jndiServer);
        remoteAccessFacade = new RemoteAccessFacade(getLog(), serverProperties);
    }

    public BareketServerImpl updateFromInjectable(MvnInjectable injectable) {
        super.updateFromMvnInjectable(injectable);
        deploymentHelper.updateFromMvnInjectable(this);
        remoteAccessFacade.setLog(getLog());
        return this;
    }

    public void start() throws MojoExecutionException {
//        if (!isJndiPortUp(serverProperties.getServerHost()) && !isJndiPortUp(serverProperties.getBackofficeHost())) {
            getLog().info(format("#### Starting Remote Servers: %s ####", jndiServer));            
            SshExecClient sshExecClient = remoteAccessFacade.getSshExec(serverProperties.getServerHost());
            sshExecClient.setTimeout(2000);
            sshExecClient.execute(serverProperties.getWebServerStartScript());
//        } else {
//            getLog().info(format("%s is already up!", jndiServer));
//        }

    }

    public void stop() throws MojoExecutionException {
//        if (isJndiPortUp(serverProperties.getServerHost()) || isJndiPortUp(serverProperties.getBackofficeHost())) {
            getLog().info(format("#### Shutting Down Remote Servers: %s ####", jndiServer));
            remoteAccessFacade.executeRemoteCommand(serverProperties.getWebServerStopScript(), serverProperties.getServerHost());
//        } else {
//            getLog().info(format("%s is already down!", jndiServer));
//        }

    }

    public void status() throws MojoExecutionException {
        boolean isUp;
        isUp = isJndiPortUp(serverProperties.getServerHost());
        getLog().info(format("server %s on %s is %s", jndiServer, serverProperties.getServerHost(), (isUp ? "up" : "down")));
        isUp = isJndiPortUp(serverProperties.getBackofficeHost());
        getLog().info(format("server %s on %s is %s", jndiServer, serverProperties.getBackofficeHost(), (isUp ? "up" : "down")));
    }

    public List<ServerDeployTypeEnum> getSupportedDeploys() {
        List<ServerDeployTypeEnum> supportedDeploys = new ArrayList<ServerDeployTypeEnum>(10);
        List<String> stringList = Arrays.asList(serverProperties.getSupportedDeploys().split(";"));

        for (final String s : stringList) {
            supportedDeploys.add(ServerDeployTypeEnum.resloveDeployType(s));
        }
        return supportedDeploys;
    }

    public ServerTypeEnum getServerType() {
        return deploymentHelper.getServerType();
    }

    private boolean isJndiPortUp(String host) {
        try {
            Socket socket = new Socket(host, 1099);
            socket.close();
        } catch (IOException e) {
            return false;
        }
        return true;
    }

}